package com.bestv.search.management.datasyn;

import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.*;
import com.bestv.search.common.model.uid.UID;
import com.bestv.search.common.util.CharUtil;
import com.bestv.search.common.util.ChineseCharToEn;
import com.bestv.search.common.util.StringConst;

import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;

/**
 * @author Michael Wang
 */
public class CmsDbSeriesSyncer extends ProgramSyncerImpl {

    final static String sDBDriver = "oracle.jdbc.driver.OracleDriver";

    final static int progValid = 1;

    String orclUrl = null;
    String encoding = "ISO8859_1";
    String user = null;
    String pass = null;
    String seriesView = null;
    String siteCode = null;

    public CmsDbSeriesSyncer() {
    }

    public CmsDbSeriesSyncer(Map<String, String> p) throws Exception {
        this.setProps(p);
        justDoIt();
    }

    @Override
    public boolean init(Map<String, String> properties) {
        if (!initLastSyncTime(StringConst.BESTV_CMS, 1, StringConst.CMS_SERIES_SYNC_TIME)) {
            return false;
        }
        if (props.get("orclUrl") == null || props.get("orclUrl").length() == 0) {
            logger.error("orclUrl is empty!");
            result = false;
            return false;
        }
        if (props.get("series") == null || props.get("series").length() == 0) {
            logger.error("series view is empty!");
            result = false;
            return false;
        }
        if (props.get("encoding") == null || props.get("encoding").length() == 0) {
            logger.warn("encoding is empty, use ISO8859_1");
        } else {
            encoding = props.get("encoding");
        }
        orclUrl = props.get("orclUrl");
        user = props.get("user");
        pass = props.get("pass");
        seriesView = props.get("series");
        siteCode = props.get("branch").toUpperCase();
        return true;
    }

    @Override
    public boolean updateProgram() throws Exception {
        logger.info("now read from cms db series and update to search's");
        thisSyncTime = lastSyncSuccessfullTime;

        Connection conn = null;
        ResultSet rs = null;
        Statement stmt = null;

        Type type = new Type();
        type.setId(4L);
        type.setName("SERIES");
        type.setDescription("SERIES");

        String syncMessage = "Success sync series from CMS system @ " + new Date();
        try {
            Class.forName(sDBDriver);
            conn = DriverManager.getConnection(orclUrl, user, pass);
            stmt = conn.createStatement();

            rs = stmt.executeQuery("select * from " + seriesView + " where update_time >= " + "to_date('"
                    + timeformat.format(lastSyncSuccessfullTime) + "','YYYY-MM-DD HH24:MI:SS') order by update_time");
            logger.info("A new batch begins at series_update_time " + timeformat.format(lastSyncSuccessfullTime));

            boolean isValid, isNew = false;
            DataSourceKey dsKey = DataSourceKeyUtil.convert(siteCode);
            while (rs.next()) {
                Series series = new Series();
                series.setHitCount(0);
                Date now = new Date();
                try {
                    isValid = rs.getInt("status") == progValid;
                    Date ut = rs.getTimestamp("update_time");
                    series.setUpdateTime(ut);
                    if (thisSyncTime == null || ut.after(thisSyncTime)) {
                        thisSyncTime = ut;
                    }

                    List<Series> sl = sm.getSeriesByCode(dsKey, rs.getString("code"));
                    if (sl != null && sl.size() > 0) {
                        isNew = false;
                        for (int x = 0; x < sl.size(); x++) {
                            Series sr = sl.get(x);
                            if (x == 0) {
                                series = sr;
                                series.setUpdateFlag(isValid ? 1 : 2);
                            } else {
                                // inform engine to delete this info's index
                                sr.setUpdateFlag(2);
                                sr.setUpdateTimeForIndex(now);
                                sr.setUpdateTimeMillis(Long.valueOf(updatetimeformat.format(ut)));
                                vm.saveUpdateInfo(dsKey, sr);
                            }
                        }
                    } else {
                        isNew = true;
                        series.setUpdateFlag(isValid ? 0 : 2);
                    }
                    series.setCode(rs.getString("code"));
                    String name = unifyStr(rs.getString("name"));
                    series.setName(name);
                    if (series.getNamePY() == null || "".equals(series.getNamePY())) {
                        String abbreviation = ChineseCharToEn.getAllFirstLetter(name);
                        String splitTokens = splitToken(name);
                        series.setNamePY(abbreviation + " " + CharUtil.charToNum(abbreviation) + " " + splitTokens);
                    }
                    series.setStatus(rs.getInt("status"));

                    String p_type = "电视剧";
                    BizType bizType = bm.getBizTypeByName(dsKey, p_type);
                    if (bizType == null) {
                        p_type = "其他";
                        bizType = bm.getBizTypeByName(dsKey, p_type);
                    }
                    series.setP_type(p_type);
                    series.setBizType(bizType);

                    series.setGenre(unifyStr(rs.getString("genre")));
                    String kws = rs.getString("keywords");
                    Set<Keyword> keys = new HashSet<Keyword>();
                    if (kws != null && kws.trim().length() != 0) {
                        String[] keywords = unifyStr(rs.getString("keywords")).split("[\\[\\]\\-,;、 ]+");
                        for (String key : keywords) {
                            if (key == null || "".equals(key))
                                continue;
                            Keyword k = km.getKeywordByName(dsKey, key);
                            if (k == null) {
                                k = new Keyword();
                                k.setKeyword(key);
                            }
                            keys.add(k);
                        }
                    }
                    series.setKeywords(keys);
                    String tgs = rs.getString("tags");
                    Set<Tag> ts = new HashSet<Tag>();
                    if (tgs != null && tgs.trim().length() != 0) {
                        String[] tags = unifyStr(rs.getString("tags")).split("[\\[\\]\\-,;、 ]+");
                        for (String tg : tags) {
                            if (tg == null || "".equals(tg))
                                continue;
                            Tag t = tm.getTagByName(dsKey, tg);
                            if (t == null) {
                                t = new Tag();
                                t.setTag(tg);
                            }
                            ts.add(t);
                        }
                    }
                    series.setTags(ts);
                    series.setType(type);
                    series.setDescription(unifyStr(rs.getString("description")));
                    String actors = unifyStr(rs.getString("actor_display"));
                    series.setActors(actors);
                    if (series.getActorsPY() == null || "".equals(series.getActorsPY())) {
                        String actorsStr = ChineseCharToEn.getAllFirstLetter(actors);
                        series.setActorsPY(actorsStr + " " + CharUtil.charToNum(actorsStr));
                    }
                    String directors = unifyStr(rs.getString("writer_display"));
                    series.setDirectors(directors);
                    if (series.getDirectorsPY() == null || "".equals(series.getDirectorsPY())) {
                        String directorStr = ChineseCharToEn.getAllFirstLetter(directors);
                        series.setDirectorsPY(directorStr + " " + CharUtil.charToNum(directorStr));
                    }
                    series.setUpdateTimeForIndex(now);
                    series.setUpdateTimeMillis(Long.valueOf(updatetimeformat.format(ut)));
                    if (isNew) {
                        series.setId(new Long(UID.getUID(series)));
                    }
                } catch (Exception e) {
                    // ignore one record exception, just log it.
                    // e.printStackTrace();
                    logger.error("read series error! pcode=" + rs.getString("code"));
                }
                vm.saveUpdateInfo(dsKey, series);
            }
            rs.close();
        } catch (Exception e) {
            System.out.println(e);
            syncMessage = "failed sync series from CMS system @ " + new Date();
            result = false;
            throw e;
        } finally {
            if (rs != null)
                rs.close();
            if (stmt != null)
                stmt.close();
            if (conn != null)
                conn.close();

            // Update Sync status.
            updateSyncStatus(StringConst.BESTV_CMS, 1, StringConst.CMS_SERIES_SYNC_TIME, syncMessage, thisSyncTime);
        }
        return true;
    }

    String unifyStr(String s) throws UnsupportedEncodingException {
        if (s == null)
            return null;
        String toCode = encoding.equalsIgnoreCase("iso-8859-1") ? "gbk" : "utf-8";
        return new String(s.getBytes(encoding), toCode).trim();
    }

}
